

local Parser = import("./Parser.lua");
local Style = commonlib.inherit(commonlib.ToolBase);

Style:Property("Element");

local function ParseStyle(style)
	if (type(style) == "string") then return Parser.ParseString(style) end 
	if (type(style) == "table") then return Parser.ParseTable(style) end 
	return {};
end

function Style:ctor()
	-- 当前样式
    self.__current_style__ = {};
	-- 内联样式
	self.__inline_style__ = {};
	-- 默认样式
	self.__default_style__ = {};
	-- 默认悬浮样式
	self.__default_hover_style__ = {};
	-- 默认聚焦样式
	self.__default_focus_style__ = {};

	-- 重置样式
	self:ResetStyleSheetStyle();
end

function Style:ResetStyleSheetStyle()
	-- 选择器集
	self.__selector__ = {};

	-- 选择器样式
	self.__selector_style__ = {};
	
	-- 伪类样式
	-- 激活样式
	self.__active_style__ = {};
	-- 悬浮样式
	self.__hover_style__ = {};
	-- 聚焦样式
	self.__focus_style__ = {};
end

function Style:ToColor(color)
	return Parser.GetColorValue(color);
end

function Style:Init(element)
    self:SetElement(element);
    return self;
end

function Style:ParseStyle(style)
	return ParseStyle(style);
end

function Style:GetSelector()
	return self.__selector__;
end

function Style:GetSelectorStyle()
	return self.__selector_style__;
end

function Style:GetActiveStyle()
	return self.__active_style__;
end

function Style:GetHoverStyle()
	return self.__hover_style__;
end

function Style:GetFocusStyle()
	return self.__focus_style__;
end

function Style:GetInlineStyle()
	return self.__inline_style__;
end

function Style:SetInlineStyle(inline_style)
	self.__inline_style__ = ParseStyle(inline_style);
end

function Style:SetDefaultStyle(default_style)
	self.__default_style__ = ParseStyle(default_style);
end

function Style:SetDefaultHoverStyle(default_hover_style)
	self.__default_hover_style__ = ParseStyle(default_hover_style);
end

function Style:SetDefaultFocusStyle(default_focus_style)
	self.__default_focus_style__ = ParseStyle(default_focus_style);
end

function Style:GetCurrentStyle()
    return self.__current_style__;
end

function Style:SetCurrentStyle(style)
	self.__current_style__ = style or self.__current_style__;
end

function Style:ApplyStyle()
    commonlib.cleartable(self.__current_style__);

	-- 默认样式
	commonlib.partialcopy(self.__current_style__, self.__default_style__);

    -- 选择器样式
    commonlib.partialcopy(self.__current_style__, self.__selector_style__);

    -- 伪类样式
	local el = self:GetElement();

	-- 悬浮
	if (el:IsHover()) then 
		commonlib.partialcopy(self.__current_style__, self.__default_hover_style__);
		commonlib.partialcopy(self.__current_style__, self.__hover_style__);
	end
    
	-- 聚焦
	if (el:IsFocus()) then 
		commonlib.partialcopy(self.__current_style__, self.__default_focus_style__);
		commonlib.partialcopy(self.__current_style__, self.__focus_style__);
	end 

    -- 内联样式最高优先级
    commonlib.partialcopy(self.__current_style__, self.__inline_style__);

	-- if (self:GetElement():GetAttrStringValue("id") == "debug") then
	-- 	commonlib.echo(self.__current_style__);
	-- 	commonlib.echo(self.__selector_style__);
	-- 	commonlib.echo(self.__inline_style__);
	-- end
end

-- 继承字段
local inheritable_fields = {
	["color"] = true,
	["font-family"] = true,
	["font-size"] = true,
	["font-weight"] = true,
	["text-shadow"] = true,
	["shadow-color"] = true,
	["text-shadow-offset-x"] = true,
	["text-shadow-offset-y"] = true,
	["text-align"] = true,
	["line-height"] = true,
	["caret-color"] = true,
	["text-singleline"] = true,
	["base-font-size"] = true,
	["white-space"] = true,
};

-- 获取样式值
function Style:GetValue(key, defaultValue)
	if (self.__current_style__[key] or not inheritable_fields[key]) then return self.__current_style__[key] or defaultValue end

    local parentElement = self:GetElement():GetParent();
    local parentStyle = parentElement and parentElement:GetStyle();

    return parentStyle and parentStyle:GetValue(key) or defaultValue;
end

function Style:GetLineHeight(defaultValue)
	local lineHeight = self:GetValue("line-height");
	if (type(lineHeight) == "number") then return lineHeight end

	local fontSize = self:GetFontSize();
	if (Parser.IsPx(lineHeight)) then 
		lineHeight = Parser.GetPxValue(lineHeight);
	elseif (Parser.IsNumber(lineHeight)) then 
		lineHeight = math.floor(Parser.GetNumberValue(lineHeight) * fontSize);
	else
		lineHeight = defaultValue or math.floor(1.4 * fontSize);
	end
	return lineHeight; 
end

function Style:GetFontSize()
	return self:GetValue("font-size", 14);
end

return Style;